package com.peas.platform.module.icims.contract.initial.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.peas.platform.common.core.dto.BaseDto;
import com.peas.platform.common.core.enums.BaseEnum;
import com.peas.platform.framework.mybatisplus.domain.BaseDomain;
import com.peas.platform.framework.mybatisplus.po.BasePo;
import com.peas.platform.framework.mybatisplus.service.BaseServiceImpl;
import com.peas.platform.module.icims.base.approve.component.ApproveCallback;
import com.peas.platform.module.icims.base.approve.dto.ApproveDto;
import com.peas.platform.module.icims.base.approve.dto.ApproveOrderNodeDto;
import com.peas.platform.module.icims.base.approve.enums.ApproveOrderBusinessType;
import com.peas.platform.module.icims.base.approve.service.ApproveOrderService;
import com.peas.platform.module.icims.base.approve.service.ApproveService;
import com.peas.platform.module.icims.base.sys.enums.CommonYesNo;
import com.peas.platform.module.icims.contract.basal.dto.ContractTypeDto;
import com.peas.platform.module.icims.contract.basal.service.ContractTypeService;
import com.peas.platform.module.icims.contract.initial.api.req.*;
import com.peas.platform.module.icims.contract.initial.api.resp.ContractLedgerResp;
import com.peas.platform.module.icims.contract.initial.api.resp.ContractStatusResp;
import com.peas.platform.module.icims.contract.initial.api.resp.ContractTop10Resp;
import com.peas.platform.module.icims.contract.initial.controller.vo.*;
import com.peas.platform.module.icims.contract.initial.domain.ContractInitialDomain;
import com.peas.platform.module.icims.contract.initial.dto.*;
import com.peas.platform.module.icims.contract.initial.enums.*;
import com.peas.platform.module.icims.contract.initial.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ContractInitialServiceImpl extends BaseServiceImpl<ContractInitialDto> implements ContractInitialService, ApproveCallback {

    private final String latest = "latest";

    @Resource
    private ContractInitialDomain contractInitialDomain;
    @Resource
    private ContractInitialParticipationService contractInitialParticipationService;
    @Resource
    private ContractInitialInspectionService contractInitialInspectionService;
    @Resource
    private ContractInitialPayeeService contractInitialPayeeService;
    @Resource
    private ContractInitialPayService contractInitialPayService;
    @Resource
    private ContractInitialFileService contractInitialFileService;
    @Resource
    private ContractInitialProcessService contractInitialProcessService;
    @Resource
    private ContractTypeService contractTypeService;
    @Resource
    private ApproveService approveService;
    @Resource
    private ApproveOrderService approveOrderService;
    @Resource
    private ContractInitialAuthorizationService contractInitialAuthorizationService;
    @Resource
    private ContractInitialCheckingService contractInitialCheckingService;
    @Resource
    private ContractInitialDisputeService contractInitialDisputeService;
    @Resource
    private ContractInitialInterruptService contractInitialInterruptService;
    @Resource
    private ContractInitialRestartService contractInitialRestartService;
    @Resource
    private ContractInitialSupplementalService contractInitialSupplementalService;
    @Resource
    private ContractInitialTerminateService contractInitialTerminateService;
    @Resource
    private ContractInitialTransferService contractInitialTransferService;
    @Resource
    private ContractInitialCashService contractInitialCashService;
    @Resource
    private ContractInitialChangeService contractInitialChangeService;
    @Resource
    private ContractInitialEffectService contractInitialEffectService;
    @Resource
    private ContractInitialCompleteService contractInitialCompleteService;
    @Resource
    private ContractInitialArchiveService contractInitialArchiveService;
    @Resource
    private ContractInitialBorrowService contractInitialBorrowService;
    @Resource
    private ContractInitialTrackingService contractInitialTrackingService;
    @Resource
    private ContractInitialRemindService contractInitialRemindService;

    @Override
    public BaseDomain<ContractInitialDto, ? extends BasePo> getDomain() {
        return contractInitialDomain;
    }

    private void checkContractInitialState(ContractInitialDto dto, ContractInitialState ... state) {
        List<ContractInitialState> states = Arrays.asList(state);
        Assert.isTrue(CollUtil.contains(BaseEnum.getKeyList(ContractInitialState.class, states), dto.getState()),
                "只有[{}]状态的合同才能操作",
                CollUtil.join(BaseEnum.getValueList(ContractInitialState.class, states), ","));
    }

    // 保存
    @Transactional
    @Override
    public ContractInitialDto saveContractInitial(SaveContractInitialReq vo) {
        ContractInitialDto cid = BeanUtil.copyProperties(vo, ContractInitialDto.class);
        if (StrUtil.isBlank(cid.getState())) {
            cid.setState(ContractInitialState.save.getKey());
        }
        int result;
        vo.setIsInterrupt(CommonYesNo.no.getKey());
        if (vo.getId() != null) {
            ContractInitialDto bean = this.getById(vo.getId());
            ContractInitialState state = BaseEnum.key2Enum(ContractInitialState.class, bean.getState());
            Assert.isTrue(ContractInitialState.save == state || ContractInitialState.revocation == state || ContractInitialState.reject == state, "初始合同[" + bean.getCode() + "]的状态为[" + state.getKey() + "-" + state.getValue() + "]，不允许修改");
            result = this.updateById(cid);
        } else {
            result = this.save(cid);
        }
        Assert.isTrue(result > 0, "保存失败");
        // participations
        List<ContractInitialParticipationDto> participations = contractInitialParticipationService.listByField("contractInitialId", cid.getId());
        contractInitialParticipationService.removeBatchByList(participations);
        if (CollUtil.isNotEmpty(vo.getParticipations())) {
            List<ContractInitialParticipationDto> list = new ArrayList<>();
            CollUtil.forEach(vo.getParticipations(), (CollUtil.Consumer<ContractInitialParticipationVo>) (value, index) -> {
                ContractInitialParticipationDto dto = BeanUtil.copyProperties(value, ContractInitialParticipationDto.class);
                dto.setContractInitialId(cid.getId());
                list.add(dto);
            });
            contractInitialParticipationService.saveBatch(list);
        }
        // inspections
        List<ContractInitialInspectionDto> inspections = contractInitialInspectionService.listByField("contractInitialId", cid.getId());
        contractInitialInspectionService.removeBatchByList(inspections);
        if (CollUtil.isNotEmpty(vo.getInspections())) {
            List<ContractInitialInspectionDto> list = new ArrayList<>();
            CollUtil.forEach(vo.getInspections(), (CollUtil.Consumer<ContractInitialInspectionVo>) (value, index) -> {
                ContractInitialInspectionDto dto = BeanUtil.copyProperties(value, ContractInitialInspectionDto.class);
                dto.setContractInitialId(cid.getId());
                list.add(dto);
            });
            contractInitialInspectionService.saveBatch(list);
        }
        // payees
        List<ContractInitialPayeeDto> payees = contractInitialPayeeService.listByField("contractInitialId", cid.getId());
        contractInitialPayeeService.removeBatchByList(payees);
        if (CollUtil.isNotEmpty(vo.getPayees())) {
            List<ContractInitialPayeeDto> list = new ArrayList<>();
            CollUtil.forEach(vo.getPayees(), (CollUtil.Consumer<ContractInitialPayeeVo>) (value, index) -> {
                ContractInitialPayeeDto dto = BeanUtil.copyProperties(value, ContractInitialPayeeDto.class);
                dto.setContractInitialId(cid.getId());
                list.add(dto);
            });
            contractInitialPayeeService.saveBatch(list);
        }
        // pays
        List<ContractInitialPayDto> pays = contractInitialPayService.listByField("contractInitialId", cid.getId());
        contractInitialPayService.removeBatchByList(pays);
        if (CollUtil.isNotEmpty(vo.getPays())) {
            List<ContractInitialPayDto> list = new ArrayList<>();
            CollUtil.forEach(vo.getPays(), (CollUtil.Consumer<ContractInitialPayVo>) (value, index) -> {
                ContractInitialPayDto dto = BeanUtil.copyProperties(value, ContractInitialPayDto.class);
                dto.setContractInitialId(cid.getId());
                list.add(dto);
            });
            contractInitialPayService.saveBatch(list);
        }
        // files
        List<ContractInitialFileDto> files = contractInitialFileService.listByField("contractInitialId", cid.getId());
        contractInitialFileService.removeBatchByList(files);
        if (CollUtil.isNotEmpty(vo.getFiles())) {
            List<ContractInitialFileDto> list = new ArrayList<>();
            CollUtil.forEach(vo.getFiles(), (CollUtil.Consumer<ContractInitialFileVo>) (value, index) -> {
                ContractInitialFileDto dto = BeanUtil.copyProperties(value, ContractInitialFileDto.class);
                dto.setContractInitialId(cid.getId());
                list.add(dto);
            });
            contractInitialFileService.saveBatch(list);
        }
        return cid;
    }

    // 提交
    @Transactional
    @Override
    public void submitContractInitial(SubmitContractInitialReq vo) {
        Assert.notNull(vo.getApproveId(), "请选择审批模版");
        SaveContractInitialReq v = BeanUtil.copyProperties(vo, SaveContractInitialReq.class);
        v.setState(ContractInitialState.submit.getKey());
        v.setParticipations(vo.getParticipations());
        v.setInspections(vo.getInspections());
        v.setPayees(vo.getPayees());
        v.setPays(vo.getPays());
        v.setFiles(vo.getFiles());
        ContractInitialDto cid = this.saveContractInitial(v);
        ApproveDto ad = approveService.getById(vo.getApproveId());
        ApproveOrderBusinessType approveOrderBusinessType = null;
        switch (cid.getKind()) {
            case "1":
                approveOrderBusinessType = ApproveOrderBusinessType.contractInitial;
                break;
            case "2":
                approveOrderBusinessType = ApproveOrderBusinessType.contractMain;
                break;
        }
        Assert.notNull(approveOrderBusinessType, "合同数据错误");
        approveOrderService.createApproveOrder(ad, BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), approveOrderBusinessType, cid.getId(), cid.getCode(), null, this.getClass());
        contractInitialProcessService.saveContractInitialProcessDto(cid, ContractInitialState.submit);
    }

    // 撤回
    @Transactional
    @Override
    public void revocationContractInitial(Long id) {
        ContractInitialDto dto = this.getById(id);
        Assert.notNull(dto, "找不到初始合同");
        this.checkContractInitialState(dto, ContractInitialState.submit);
        dto.setState(ContractInitialState.revocation.getKey());
        this.updateById(dto);
        ApproveOrderBusinessType approveOrderBusinessType = null;
        switch (dto.getKind()) {
            case "1":
                approveOrderBusinessType = ApproveOrderBusinessType.contractInitial;
                break;
            case "2":
                approveOrderBusinessType = ApproveOrderBusinessType.contractMain;
                break;
        }
        Assert.notNull(approveOrderBusinessType, "合同数据错误");
        approveOrderService.revocationApproveOrder(approveOrderBusinessType, id);
    }

    // 生效
    @Transactional
    @Override
    public void effectContractInitial(Long id, EffectContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.pass);
        dto.setState(ContractInitialState.effect.getKey());
        this.updateById(dto);
        contractInitialEffectService.effectContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
        contractInitialProcessService.saveContractInitialProcessDto(dto, ContractInitialState.effect);
    }

    // 请款，需要审批
    @Transactional
    @Override
    public void cashContractInitial(Long id, CashContractInitialReq vo) {
        Assert.notNull(id, "合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        ContractTypeDto type = contractTypeService.getById(dto.getType());
        boolean needPay = !StrUtil.equals(type.getCatalog(), "3");
        boolean needInspection = StrUtil.equals(CommonYesNo.yes.getKey(), dto.getNeedInspection());
        log.debug("needPay:" + needPay);
        log.debug("needInspection:" + needInspection);
        Assert.isTrue(needPay, "该合同[{}]属于其他类，不支持请款操作", dto.getCode());
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying);
        contractInitialCashService.cashContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 验收，需要审批
    @Transactional
    @Override
    public void checkingContractInitial(Long id, CheckingContractInitialReq vo) {
        Assert.notNull(id, "合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        ContractTypeDto type = contractTypeService.getById(dto.getType());
        boolean needPay = !StrUtil.equals(type.getCatalog(), "3");
        boolean needInspection = StrUtil.equals(CommonYesNo.yes.getKey(), dto.getNeedInspection());
        log.debug("needPay:" + needPay);
        log.debug("needInspection:" + needInspection);
        Assert.isTrue(needInspection, "该合同[{}]不需要验收", dto.getCode());
        if (needPay) {
            this.checkContractInitialState(dto, ContractInitialState.payed, ContractInitialState.checking);
        } else {
            this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.checking);
        }
        contractInitialCheckingService.checkingContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 完结
    @Transactional
    @Override
    public void completeContractInitial(Long id, CompleteContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        ContractTypeDto type = contractTypeService.getById(dto.getType());
        boolean needPay = !StrUtil.equals(type.getCatalog(), "3");
        boolean needInspection = StrUtil.equals(CommonYesNo.yes.getKey(), dto.getNeedInspection());
        log.debug("needPay:" + needPay);
        log.debug("needInspection:" + needInspection);
        if (needInspection) {
            this.checkContractInitialState(dto, ContractInitialState.checked);
        } else if (needPay) {
            this.checkContractInitialState(dto, ContractInitialState.payed);
        } else {
            this.checkContractInitialState(dto, ContractInitialState.effect);
        }
        dto.setState(ContractInitialState.complete.getKey());
        this.updateById(dto);
        contractInitialCompleteService.completeContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
        contractInitialProcessService.saveContractInitialProcessDto(dto, ContractInitialState.complete);
    }

    // 归档
    @Transactional
    @Override
    public void archiveContractInitial(Long id, ArchiveContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.complete);
        dto.setState(ContractInitialState.archive.getKey());
        this.updateById(dto);
        contractInitialArchiveService.archiveContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
        contractInitialProcessService.saveContractInitialProcessDto(dto, ContractInitialState.archive);
    }

    // 中止，需要审批
    @Transactional
    @Override
    public void interruptContractInitial(Long id, InterruptContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        Assert.isTrue(dto.getIsInterrupt() == null || dto.getIsInterrupt().equals(CommonYesNo.no.getKey()), "该初始合同已经中止了");
        contractInitialInterruptService.interruptContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 重启
    @Transactional
    @Override
    public void restartContractInitial(Long id, RestartContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        Assert.equals(dto.getIsInterrupt(), CommonYesNo.yes.getKey(), "该初始合同出于非中止状态");
        dto.setIsInterrupt(CommonYesNo.no.getKey());
        this.updateById(dto);
        contractInitialRestartService.restartContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 补充协议，需要审批
    @Transactional
    @Override
    public void supplementalContractInitial(Long id, SupplementalContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        contractInitialSupplementalService.supplementalContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 变更，需要审批
    @Transactional
    @Override
    public void changeContractInitial(Long id, ChangeContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        contractInitialChangeService.changeContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 转交
    @Transactional
    @Override
    public void transferContractInitial(Long id, TransferContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        contractInitialTransferService.transferContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 纠纷
    @Transactional
    @Override
    public void disputeContractInitial(Long id, DisputeContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        contractInitialDisputeService.disputeContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 授权
    @Transactional
    @Override
    public void authorizationContractInitial(Long id, AuthorizationContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        contractInitialAuthorizationService.authorizationContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 终止，需要审批
    @Transactional
    @Override
    public void terminateContractInitial(Long id, TerminateContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked);
        contractInitialTerminateService.terminateContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 借阅，需要审批
    @Transactional
    @Override
    public void borrowContractInitial(Long id, BorrowContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked, ContractInitialState.complete);
        contractInitialBorrowService.borrowContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 跟踪
    @Transactional
    @Override
    public void trackingContractInitial(Long id, TrackingContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked, ContractInitialState.complete);
        contractInitialTrackingService.trackingContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    // 提醒
    @Transactional
    @Override
    public void remindContractInitial(Long id, RemindContractInitialReq vo) {
        Assert.notNull(id, "初始合同ID不能为空");
        Assert.notEmpty(vo.getItems(), "数据为空");
        ContractInitialDto dto = this.getById(id);
        this.checkContractInitialState(dto, ContractInitialState.effect, ContractInitialState.paying, ContractInitialState.payed, ContractInitialState.checking, ContractInitialState.checked, ContractInitialState.complete);
        contractInitialRemindService.remindContractInitial(dto, vo.getApproveId(), BeanUtil.copyToList(vo.getApproveNodes(), ApproveOrderNodeDto.class), vo.getItems());
    }

    @Override
    public ContractLedgerResp getContractLedger() {
        DateTime now = DateTime.now();
        List<ContractTypeDto> list = contractTypeService.list();
        //收款类
        List<Long> types1 = list.stream().filter(dto -> StrUtil.equals("1", dto.getCatalog())).map(BaseDto::getId).collect(Collectors.toList());
        //付款类
        List<Long> types2 = list.stream().filter(dto -> StrUtil.equals("2", dto.getCatalog())).map(BaseDto::getId).collect(Collectors.toList());
        //其他类
        List<Long> types3 = list.stream().filter(dto -> StrUtil.equals("3", dto.getCatalog())).map(BaseDto::getId).collect(Collectors.toList());
        ContractLedgerResp r = new ContractLedgerResp();
        ContractInitialDto c1 = new ContractInitialDto();
        r.setValue1(this.count(c1));
        ContractInitialDto c2 = new ContractInitialDto();
        c2.setCreateTimeStart(DateUtil.beginOfMonth(now));
        c2.setCreateTimeEnd(DateUtil.endOfMonth(now));
        r.setValue2(this.count(c2));
        ContractInitialDto c3 = new ContractInitialDto();
        c3.setCreateTimeStart(DateUtil.beginOfYear(now));
        c3.setCreateTimeEnd(DateUtil.endOfYear(now));
        r.setValue3(this.count(c3));
        ContractInitialDto c4 = new ContractInitialDto();
        r.setValue4(contractInitialDomain.count("type", types2, c4));
        ContractInitialDto c5 = new ContractInitialDto();
        c5.setCreateTimeStart(DateUtil.beginOfMonth(now));
        c5.setCreateTimeEnd(DateUtil.endOfMonth(now));
        r.setValue5(contractInitialDomain.count("type", types2, c5));
        ContractInitialDto c6 = new ContractInitialDto();
        c6.setCreateTimeStart(DateUtil.beginOfYear(now));
        c6.setCreateTimeEnd(DateUtil.endOfYear(now));
        r.setValue6(contractInitialDomain.count("type", types2, c6));
        ContractInitialDto c7 = new ContractInitialDto();
        r.setValue7(contractInitialDomain.count("type", types1, c7));
        ContractInitialDto c8 = new ContractInitialDto();
        c8.setCreateTimeStart(DateUtil.beginOfMonth(now));
        c8.setCreateTimeEnd(DateUtil.endOfMonth(now));
        r.setValue8(contractInitialDomain.count("type", types1, c8));
        ContractInitialDto c9 = new ContractInitialDto();
        c9.setCreateTimeStart(DateUtil.beginOfYear(now));
        c9.setCreateTimeEnd(DateUtil.endOfYear(now));
        r.setValue9(contractInitialDomain.count("type", types1, c9));
        ContractInitialDto c10 = new ContractInitialDto();
        r.setValue10(contractInitialDomain.count("type", types3, c10));
        ContractInitialDto c11 = new ContractInitialDto();
        c11.setCreateTimeStart(DateUtil.beginOfMonth(now));
        c11.setCreateTimeEnd(DateUtil.endOfMonth(now));
        r.setValue11(contractInitialDomain.count("type", types3, c11));
        ContractInitialDto c12 = new ContractInitialDto();
        c12.setCreateTimeStart(DateUtil.beginOfYear(now));
        c12.setCreateTimeEnd(DateUtil.endOfYear(now));
        r.setValue12(contractInitialDomain.count("type", types3, c12));
        return r;
    }

    @Override
    public ContractStatusResp getContractStatus() {
        ContractStatusResp r = new ContractStatusResp();
        // TODO
        r.setValue1(1L);
        r.setValue2(22L);
        r.setValue3(333L);
        return r;
    }

    @Override
    public List<ContractTop10Resp> getContractTop10() {
        List<ContractTop10Resp> r = new ArrayList<>();
        // TODO
        for (int i = 0; i < 10; i++) {
            ContractTop10Resp c = new ContractTop10Resp();
            c.setValue1("企业" + (i+1));
            c.setValue2((10-i) * 2);
            r.add(c);
        }
        return r;
    }

    @Transactional
    @Override
    public void callbackAfterApprove(Long businessId, boolean isPass, boolean isFinalPass) {
        if (businessId == null)
            return;
        if (isPass) {
            if (isFinalPass) {
                ContractInitialDto cid = this.getById(businessId);
                cid.setState(ContractInitialState.pass.getKey());
                this.updateById(cid);
                contractInitialProcessService.saveContractInitialProcessDto(cid, ContractInitialState.pass);
                // 生成合同执行明细-验收
                this.genChecking(cid);
                // 生成合同执行明细-请款
                this.genCash(cid);
            }
        } else {
            ContractInitialDto cid = this.getById(businessId);
            cid.setState(ContractInitialState.reject.getKey());
            this.updateById(cid);
        }
    }

    private void genChecking(ContractInitialDto cid) {
        List<ContractInitialInspectionDto> list1 = contractInitialInspectionService.listByField("contractInitialId", cid.getId());
        if (CollUtil.isNotEmpty(list1)) {
            List<ContractInitialCheckingDto> checkings = new ArrayList<>();
            for (ContractInitialInspectionDto dto : list1) {
                ContractInitialCheckingDto item = new ContractInitialCheckingDto();
                item.setContractInitialId(dto.getContractInitialId());
                item.setBatch(latest);
                item.setContractInitialInspectionId(dto.getId());
                item.setPrincipalUserId(dto.getPrincipalUserId());
                item.setState(ContractInitialCheckingState.save.getKey());
                checkings.add(item);
            }
            contractInitialCheckingService.saveBatch(checkings);
        }
    }

    private void genCash(ContractInitialDto cid) {
        List<ContractInitialPayDto> list2 = contractInitialPayService.listByField("contractInitialId", cid.getId());
        if (CollUtil.isNotEmpty(list2)) {
            List<ContractInitialCashDto> cashs = new ArrayList<>();
            for (ContractInitialPayDto dto : list2) {
                ContractInitialCashDto item = new ContractInitialCashDto();
                item.setContractInitialId(dto.getContractInitialId());
                item.setBatch(latest);
                item.setCashType("2");
                item.setCashAmount(dto.getAmount());
                item.setState(ContractInitialCashState.save.getKey());
                cashs.add(item);
            }
            contractInitialCashService.saveBatch(cashs);
        }
        List<ContractInitialPayeeDto> list3 = contractInitialPayeeService.listByField("contractInitialId", cid.getId());
        if (CollUtil.isNotEmpty(list3)) {
            List<ContractInitialCashDto> cashs = new ArrayList<>();
            for (ContractInitialPayeeDto dto : list3) {
                ContractInitialCashDto item = new ContractInitialCashDto();
                item.setContractInitialId(dto.getContractInitialId());
                item.setBatch(latest);
                item.setCashType("1");
                item.setCashAmount(dto.getAmount());
                item.setState(ContractInitialCashState.save.getKey());
                cashs.add(item);
            }
            contractInitialCashService.saveBatch(cashs);
        }
    }

}
